package com.efast.dmom.mgmt.service.les.impl;

import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.framework.jdbc.JdbcDao;
import com.efast.dmom.mgmt.bean.les.pda.PdaTwInvPacktranDetail;
import com.efast.dmom.mgmt.dao.les.*;
import com.efast.dmom.mgmt.entity.les.TrBasPartStorage;
import com.efast.dmom.mgmt.entity.les.TwInvPacktranDetail;
import com.efast.dmom.mgmt.entity.les.TwInvPacktranHeader;
import com.efast.dmom.mgmt.entity.les.TwInvSkuLoctl;
import com.efast.dmom.mgmt.service.les.TwInvPacktranHeaderService;
import com.efast.dmom.mgmt.utils.Assist;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chlp
 */
@Service("twInvPacktranHeaderServiceImpl")
public class TwInvPacktranHeaderServiceImpl implements TwInvPacktranHeaderService {

	/**
	 *
	 * 补货任务头表 TW_INV_PACKTRAN_HEADER
	 */
	private final TwInvPacktranHeaderDao twInvPacktranHeaderDao;
	/**
	 *
	 * 补货任务明细 TW_INV_PACKTRAN_DETAIL
	 */
	private final TwInvPacktranDetailDao twInvPacktranDetailDao;
	/**
	 *
	 * 批次跟踪号库存表 tw_inv_sku_loc_t_l
	 */
	private final TwInvSkuLoctlDao twInvSkuLoctlDao;
	/**
	 *
	 * 出库记录表 tt_whm_stock_outbound
	 */
	private final TtWhmStockOutboundDao ttWhmStockOutboundDao;

	private final TrBasPartStorageDao trBasPartStorageDao;

	@Qualifier("jdbcDao")
	@Autowired
	private JdbcDao jdbcDao;

	@Autowired
	public TwInvPacktranHeaderServiceImpl(TwInvPacktranHeaderDao twInvPacktranHeaderDao,
			TwInvPacktranDetailDao twInvPacktranDetailDao, TwInvSkuLoctlDao twInvSkuLoctlDao,
			TtWhmStockOutboundDao ttWhmStockOutboundDao, TrBasPartStorageDao trBasPartStorageDao) {
		this.twInvPacktranHeaderDao = twInvPacktranHeaderDao;
		this.twInvPacktranDetailDao = twInvPacktranDetailDao;
		this.twInvSkuLoctlDao = twInvSkuLoctlDao;
		this.ttWhmStockOutboundDao = ttWhmStockOutboundDao;
		this.trBasPartStorageDao = trBasPartStorageDao;
	}

	/**
	 * 补货完成逻辑： 1拣货完成-单据状态变成拣货完成 2确认完成-单据状态变成补货完成，库存转移 但是目前没有RF端，所以在Pc端，一步到位直接补货完成。扣库存
	 */
	@Override
	public void replenishmentFinish(TwInvPacktranHeader twInvPacktranHeader) {
		List<TwInvPacktranDetail> listTwInvPacktranDetail = twInvPacktranDetailDao.selectTwInvPacktranDetail(
				new Assist(Assist.andEq("tw_inv_packtran_header_id", twInvPacktranHeader.getTwInvPacktranHeaderId())));
		// 补货类型（1即时补货 2按库存消耗补货 3按累计消耗补货）
		String packtranType = twInvPacktranHeader.getPacktranType();
		// 【1】即时补货/窗口补货-按累计消耗：指定源库位-目标库位，系统无需分配库位
		if ("1".equals(packtranType) || "3".equals(packtranType)) {
			// 遍历所有的补货任务明细 TW_INV_PACKTRAN_DETAIL
			for (TwInvPacktranDetail twInvPacktranDetail : listTwInvPacktranDetail) {
				List<TwInvSkuLoctl> listTwInvSkuLoctl = twInvSkuLoctlDao.selectTwInvSkuLoctl(
						new Assist(Assist.andEq("tm_bas_storage_id", twInvPacktranDetail.getPFromLocId()),
								Assist.andEq("part_no_version", twInvPacktranDetail.getPartNoVersion())));
				if (listTwInvSkuLoctl.size() == 0) {
					throw new ServiceException(twInvPacktranDetail.getPartNoVersion() + "源库位"
							+ twInvPacktranDetail.getPFromLocId() + "没有可扣库存");
				}
				// 要求补货包装数量
				Integer prePacktranQty = twInvPacktranDetail.getPrePacktranQty();
				deductingInventory(twInvPacktranDetail, listTwInvSkuLoctl, prePacktranQty);
				// 更新 TW_INV_PACKTRAN_DETAIL 的状态为补货完成。
				TwInvPacktranDetail twInvPacktranDetail2 = new TwInvPacktranDetail();
				twInvPacktranDetail2.setTwInvPacktranDetailId(twInvPacktranDetail.getTwInvPacktranDetailId());
				// 补货任务行状态 0:新任务，1：补货完成
				twInvPacktranDetail2.setTaskStatue("1");
				twInvPacktranDetailDao.updateNonEmptyTwInvPacktranDetailById(twInvPacktranDetail2);
			}
		}
		// 窗口时间-按库存消耗：不会指定到源库位，系统需要分配出库库位。
		if ("2".equals(packtranType)) {
			for (TwInvPacktranDetail twInvPacktranDetail : listTwInvPacktranDetail) {
				// 根据零件号 去 零件仓库关系（tr_bas_part_storage）找一个库位
				List<TrBasPartStorage> listTrBasPartStorage = trBasPartStorageDao.selectTrBasPartStorage(new Assist(
						Assist.andEq("tr_bas_part_storage.part_no_version", twInvPacktranDetail.getPartNoVersion())));
				if (listTrBasPartStorage.size() == 0) {
					throw new ServiceException(twInvPacktranDetail.getPartNoVersion() + "找不到对应的仓库关系，无法分配库位");
				}
				List<TwInvSkuLoctl> listTwInvSkuLoctl = twInvSkuLoctlDao.selectTwInvSkuLoctl(
						new Assist(Assist.andEq("tm_bas_storage_id", listTrBasPartStorage.get(0).getLocId()),
								Assist.andEq("part_no_version", twInvPacktranDetail.getPartNoVersion())));
				if (listTwInvSkuLoctl.size() == 0) {
					throw new ServiceException(twInvPacktranDetail.getPartNoVersion() + "没有可扣库存");
				}
				// 要求补货包装数量
				Integer prePacktranQty = twInvPacktranDetail.getPrePacktranQty();
				deductingInventory(twInvPacktranDetail, listTwInvSkuLoctl, prePacktranQty);
				// 更新 TW_INV_PACKTRAN_DETAIL 的状态为补货完成。
				TwInvPacktranDetail twInvPacktranDetail2 = new TwInvPacktranDetail();
				twInvPacktranDetail2.setTwInvPacktranDetailId(twInvPacktranDetail.getTwInvPacktranDetailId());
				// 补货任务行状态 0:新任务，1：补货完成
				twInvPacktranDetail2.setTaskStatue("1");
				twInvPacktranDetailDao.updateNonEmptyTwInvPacktranDetailById(twInvPacktranDetail2);
			}
		}
	}

	/**
	 * 扣除库存
	 *
	 * @param twInvPacktranDetail
	 *            补货明细记录
	 * @param listTwInvSkuLoctl
	 *            可以扣库的记录
	 * @param prePacktranQty
	 *            要求补货包装数量
	 */
	private void deductingInventory(TwInvPacktranDetail twInvPacktranDetail, List<TwInvSkuLoctl> listTwInvSkuLoctl,
			Integer prePacktranQty) {
		// 如果一条记录就满足，需要扣减的数量<一条记录的可用库存
		if (twInvPacktranDetail.getPrePacktranQty() < listTwInvSkuLoctl.get(0).getCurQty()) {
			TwInvSkuLoctl twInvSkuLoctl3 = new TwInvSkuLoctl();
			twInvSkuLoctl3.setTwInvSkuLoctlId(listTwInvSkuLoctl.get(0).getTwInvSkuLoctlId());
			twInvSkuLoctl3.setCurQty(listTwInvSkuLoctl.get(0).getCurQty() - prePacktranQty);
			twInvSkuLoctl3.setAvailableQty(listTwInvSkuLoctl.get(0).getAvailableQty() - prePacktranQty);
			twInvSkuLoctlDao.updateNonEmptyTwInvSkuLoctlById(twInvSkuLoctl3);
			// 【3】：扣库完成后，需要写入出库记录(tt_whm_stock_outbound)，供后续库存追溯
			// insertNonEmptyTtWhmStockOutbound(twInvPacktranDetail, listTwInvSkuLoctl);
		} else {
			// 不满足，则循环扣库
			double sumQty = 0;
			for (TwInvSkuLoctl twInvSkuLoctl : listTwInvSkuLoctl) {
				sumQty += twInvSkuLoctl.getAvailableQty();
			}
			if (twInvPacktranDetail.getPrePacktranQty() > sumQty) {
				throw new ServiceException(twInvPacktranDetail.getPartNoVersion() + "当前可用库存小于消耗");
			}
			for (TwInvSkuLoctl twInvSkuLoctl : listTwInvSkuLoctl) {
				if (twInvPacktranDetail.getPrePacktranQty() > twInvSkuLoctl.getAvailableQty()) {
					TwInvSkuLoctl twInvSkuLoctl3 = new TwInvSkuLoctl();
					twInvSkuLoctl3.setTwInvSkuLoctlId(twInvSkuLoctl.getTwInvSkuLoctlId());
					twInvSkuLoctl3.setCurQty(0);
					twInvSkuLoctl3.setAvailableQty(0);
					twInvSkuLoctlDao.updateNonEmptyTwInvSkuLoctlById(twInvSkuLoctl3);
					// 【3】：扣库完成后，需要写入出库记录(tt_whm_stock_outbound)，供后续库存追溯
					// insertNonEmptyTtWhmStockOutbound(twInvPacktranDetail, listTwInvSkuLoctl);
				} else {
					TwInvSkuLoctl twInvSkuLoctl3 = new TwInvSkuLoctl();
					twInvSkuLoctl3.setTwInvSkuLoctlId(twInvSkuLoctl.getTwInvSkuLoctlId());
					twInvSkuLoctl3.setCurQty(twInvSkuLoctl.getAvailableQty() - twInvPacktranDetail.getPrePacktranQty());
					twInvSkuLoctl3.setAvailableQty(
							twInvSkuLoctl.getAvailableQty() - twInvPacktranDetail.getPrePacktranQty());
					twInvSkuLoctlDao.updateNonEmptyTwInvSkuLoctlById(twInvSkuLoctl3);
					// 【3】：扣库完成后，需要写入出库记录(tt_whm_stock_outbound)，供后续库存追溯
					// insertNonEmptyTtWhmStockOutbound(twInvPacktranDetail, listTwInvSkuLoctl);
					break;
				}
				prePacktranQty = prePacktranQty - twInvSkuLoctl.getAvailableQty();
			}
		}
	}

	// 扣库完成后，需要写入出库记录(tt_whm_stock_outbound)，供后续库存追溯
	// 所有出库 都要记录出库记录 也就是发运以后
	// 理论上所有的库存交易都要需要记录交易记录 包括补货完成 库存移动 调整等等
	// 但是这些太多 我们这期不做,只做出入库的报表 也就是出入库记录
	// public void insertNonEmptyTtWhmStockOutbound(TwInvPacktranDetail
	// twInvPacktranDetail,
	// List<TwInvSkuLoctl> listTwInvSkuLoctl) {
	//
	// TtWhmStockOutbound ttWhmStockOutbound = new TtWhmStockOutbound();
	// ttWhmStockOutbound.setTrBasPartSupplId(listTmBasPullUnit.get(0).getTrBasPartSupplId());//
	// 零件供应商关系ID
	// ttWhmStockOutbound.setStockPartLotNo(listTwInvSkuLoctl.get(0).getLotNo()); //
	// 零件批次号
	// List<TmBasPart> listTmBasPart = trBasPartDao
	// .selectTmBasPart(new Assist(Assist.andEq("part_no_version",
	// twInvPacktranDetail.getPartNoVersion())));
	// ttWhmStockOutbound.setTmBasPartId(listTmBasPart.get(0).getTmBasPartId()); //
	// 零件ID
	// ttWhmStockOutbound.setOutboundQty(twInvPacktranDetail.getPrePacktranQty());//
	// 出库数量 -- >要求补货包装数量
	// ttWhmStockOutbound.setOutboundUsername(SpringWebUtils.getRequestUser()); //
	// 入库人
	// ttWhmStockOutbound.setOutboundTime(new Date()); // 入库时间
	// ttWhmStockOutbound.setWarehouseId(twInvPacktranDetail.getAfterPartWarehouse());
	// // 仓库id
	// ttWhmStockOutbound.setWarehouseNo(twInvPacktranDetail.getAfterPartWarehouse());
	// // 仓库编号
	// ttWhmStockOutbound.setDlocId(twInvPacktranDetail.getAfterPartDloc()); // 库区
	// ttWhmStockOutbound.setDlocNo(twInvPacktranDetail.getAfterPartDloc()); // 库区编号
	// ttWhmStockOutbound.setLocId(twInvPacktranDetail.getAfterPartLoc()); // 库位
	// ttWhmStockOutbound.setLocNo(twInvPacktranDetail.getAfterPartLoc()); // 库位编号
	// ttWhmStockOutbound.setTmBasPlantId(listTmBasPullUnit.get(0).getTmBasPlantId());
	// // 工厂
	// ttWhmStockOutbound.setTmBasWorkshopId(listTmbuBasPullUnit.get(0).getTmBasWorkshopId());//
	// 车间
	// ttWhmStockOutbound.setSheetNo(teMesOutbound.getOrderNo()); // 对应单证编号
	// ttWhmStockOutbound.setCommonSheetType("14"); // 对应单证类型
	// ttWhmStockOutbound.setCurPackageNum(teMesOutbound.getPartQty() /
	// listTmBasPullUnit.get(0).getStationPullQty());// 当前箱数
	// List<TmBasDeliveryUnit> listTmBasDeliveryUnit =
	// tmBasDeliveryUnitDao.selectTmBasDeliveryUnit(
	// new Assist(Assist.andEq("delivery_unit_no",
	// listTmBasPullUnit.get(0).getDeliveryUnitNo())));
	// ttWhmStockOutbound.setTmBasDeliveryUnitId(listTmBasDeliveryUnit.get(0).getTmBasDeliveryUnitId());//
	// 收货地
	// List<TmBasDeliveryUnit> listTmBasDeliveryUnit2 =
	// tmBasDeliveryUnitDao.selectTmBasDeliveryUnit(
	// new Assist(Assist.andEq("delivery_unit_no",
	// listTmBasPullUnit.get(0).getDeliveryUnitNo())));
	// ttWhmStockOutbound.setDeliveryRec(listTmBasDeliveryUnit2.get(0).getTmBasDeliveryUnitId());//
	// 目的地
	// ttWhmStockOutbound.setTmBasSupplId(listTmBasPullUnit.get(0).getTrBasPartSupplId());//
	// 供应商本地标识码
	// // ttWhmStockOutbound.setOutBoundGroupId(null); // 入库组号
	// // ttWhmStockOutbound.setSheetId(); // 对应单证ID
	// //
	// ttWhmStockOutbound.setDlocPackageSysid(listTrBasPartStorage.get(0).getPartPackageId());
	// // ttWhmStockOutbound.setInterfaceGroupId();// 接口汇总组号
	// // ttWhmStockOutbound.setPoType(); // 拉动单类型
	// // ttWhmStockOutbound.setVin(vin); // VIN号 预留字段 目前不用
	// // ttWhmStockOutbound.setToOutboundFalg(toOutboundFalg); // 生成出库记录标记(外排序单)
	// ttWhmStockOutbound.setFlag(0); // 冲销标记
	// ttWhmStockOutbound.setIsTosap("0"); // 是否已上传SAP
	// ttWhmStockOutbound.setIsCanTosap("1");// 是否允许上传SAP0不允许1允许
	// ttWhmStockOutbound.setBaseUnit("EA");// 基本单位
	// ttWhmStockOutbound.setMriStatus("0");// 补货需求状态(0:未组织,1:已组织)
	// ttWhmStockOutbound.setMarkStatus(1);
	// ttWhmStockOutbound.setCompanyCode(SpringWebUtils.getRequestCompany());
	// ttWhmStockOutbound.setCreateTime(new Date());
	// ttWhmStockOutbound.setCreateUser(SpringWebUtils.getRequestUser());
	// ttWhmStockOutboundDao.insertNonEmptyTtWhmStockOutbound(ttWhmStockOutbound);
	// }

	@Override
	public Map<String, Object> insertNonEmptyTwInvPacktranHeader(TwInvPacktranHeader value) {
		String packtranSheetNo = jdbcDao.executeProcGetCode("tw_inv_packtran_header", "efast");
		// 补货任务单号
		value.setPacktranSheetNo(packtranSheetNo);
		twInvPacktranHeaderDao.insertNonEmptyTwInvPacktranHeader(value);
		Map<String, Object> map = new HashMap<>();
		map.put("packtranSheetNo", packtranSheetNo);
		map.put("twInvPacktranHeaderId", value.getTwInvPacktranHeaderId());
		return map;
	}

	@Override
	public long getTwInvPacktranHeaderRowCount(Assist assist) {
		return twInvPacktranHeaderDao.getTwInvPacktranHeaderRowCount(assist);
	}

	@Override
	public List<TwInvPacktranHeader> selectTwInvPacktranHeader(Assist assist) {
		return twInvPacktranHeaderDao.selectTwInvPacktranHeader(assist);
	}

	@Override
	public TwInvPacktranHeader selectTwInvPacktranHeaderByObj(TwInvPacktranHeader obj) {
		return twInvPacktranHeaderDao.selectTwInvPacktranHeaderByObj(obj);
	}

	@Override
	public TwInvPacktranHeader selectTwInvPacktranHeaderById(Integer id) {
		return twInvPacktranHeaderDao.selectTwInvPacktranHeaderById(id);
	}

	@Override
	public int insertTwInvPacktranHeader(TwInvPacktranHeader value) {
		return twInvPacktranHeaderDao.insertTwInvPacktranHeader(value);
	}

	@Override
	public int insertTwInvPacktranHeaderByBatch(List<TwInvPacktranHeader> value) {
		return twInvPacktranHeaderDao.insertTwInvPacktranHeaderByBatch(value);
	}

	@Override
	public int deleteTwInvPacktranHeaderById(Integer id) {
		return twInvPacktranHeaderDao.deleteTwInvPacktranHeaderById(id);
	}

	@Override
	public int deleteTwInvPacktranHeader(Assist assist) {
		return twInvPacktranHeaderDao.deleteTwInvPacktranHeader(assist);
	}

	@Override
	public int updateTwInvPacktranHeaderById(TwInvPacktranHeader enti) {
		return twInvPacktranHeaderDao.updateTwInvPacktranHeaderById(enti);
	}

	@Override
	public int updateTwInvPacktranHeader(TwInvPacktranHeader value, Assist assist) {
		return twInvPacktranHeaderDao.updateTwInvPacktranHeader(value, assist);
	}

	@Override
	public int updateNonEmptyTwInvPacktranHeaderById(TwInvPacktranHeader enti) {
		return twInvPacktranHeaderDao.updateNonEmptyTwInvPacktranHeaderById(enti);
	}

	@Override
	public int updateNonEmptyTwInvPacktranHeader(TwInvPacktranHeader value, Assist assist) {
		return twInvPacktranHeaderDao.updateNonEmptyTwInvPacktranHeader(value, assist);
	}
	/**
	 * 7.5.4.3获取补货任务查询接口
	 *
	 * @param pdaTwInvPacktranDetail
	 *            pdaTwInvPacktranDetail
	 * @return List<TwInvPacktranDetail>
	 */
	@Override
	public List<TwInvPacktranDetail> queryInvPacktran(PdaTwInvPacktranDetail pdaTwInvPacktranDetail) {
		List<TwInvPacktranHeader> twInvPacktranDetails = null;
		if (pdaTwInvPacktranDetail.getRebRoad() != null) {
			twInvPacktranDetails = twInvPacktranHeaderDao.selectTwInvPacktranHeader(
					new Assist(Assist.andEq("reb_road", pdaTwInvPacktranDetail.getRebRoad()),
							Assist.andEq("packtran_status", "0")));
		}
		Assist assist = new Assist();
		if (pdaTwInvPacktranDetail.getAfterPartLoc() != null) {
			assist.setRequires(Assist.andEq("after_part_loc", pdaTwInvPacktranDetail.getAfterPartLoc()));
		}
		if (pdaTwInvPacktranDetail.getPacktranSheetNo() != null) {
			assist.setRequires(Assist.andEq("packtran_sheet_no", pdaTwInvPacktranDetail.getPacktranSheetNo()));
		}
		if (pdaTwInvPacktranDetail.getPartNoVersion() != null) {
			assist.setRequires(Assist.andEq("part_no_version", pdaTwInvPacktranDetail.getPartNoVersion()));
		}
		if (twInvPacktranDetails != null) {
			assist.setRequires(
					Assist.andEq("tw_inv_packtran_header_id", twInvPacktranDetails.get(0).getTwInvPacktranHeaderId()));
		}
		// '0:新任务，1：任务确认,2:部分分配，3：分配完成，4：分配失败，5：部分拣货，6拣货完成，7任务完成，8：关闭，9：补货失败
		assist.setRequires(Assist.orEq("task_statue", "5"));
		assist.setRequires(Assist.orEq("task_statue", "6"));
		// 是否需要分配库存(0:无来源库位需要分配|1：有来源库位，不需要分配)
		assist.setRequires(Assist.orEq("acall_flag", "0"));
		return twInvPacktranDetailDao.selectTwInvPacktranDetail(assist);
	}
}